package main.movie;

import java.io.FileNotFoundException;

import parse.*;
import Const.Constant;
import ExecuteEngine.*;
import IndexComponent.IX_IndexHandle;
import IndexComponent.IX_IndexScan;
import IndexComponent.StringKeyword;
import RecordManagement.RID;
import RecordManagement.RM_FileHandle;
import SystemManagement.*;

public class test {
	public static void main(String[] args) throws FileNotFoundException {
		SM_Manager sm = new SM_Manager();
		
//		sm.CreateDB("miniDB");
		sm.OpenDb("miniDB");
		
	
//		new test().Explain("CREATE TABLE studio (name VARCHAR(20) primary key ,ID varchar(10))", sm);
//		new test().Explain("insert into studio values('Studio A', '125345')", sm);
//		new test().Explain("insert into studio values('Studio B', '563456')", sm);
//		new test().Explain("insert into studio values('Studio C', '657457')", sm);
//		new test().Explain("insert into studio values('Studio D', '865458')", sm);
//		new test().Explain("insert into studio values('Studio E', '353445')", sm);
//		new test().Explain("insert into studio values('Studio F', '167459')", sm);
		
		
		
//		new test().Explain("create table movies(title char(20),year integer,studio char(30) references studio(name),primary key(title, year))", sm);
//		new test().Explain("insert into movies values('Star Wars', 1999, 'Studio A')", sm);
//		new test().Explain("insert into movies values('Star Wars', 2001, 'Studio A')", sm);
//		new test().Explain("insert into movies values('Pretty Woman', 1999, 'Studio B')", sm);
//		new test().Explain("insert into movies values('Titanic', 1997, 'Studio B')", sm);
//		new test().Explain("insert into movies values('WALL-E', 2008, 'Studio C')", sm);
//		new test().Explain("insert into movies values('UP', 2009, 'Studio C')", sm);
//		new test().Explain("insert into movies values('Mickey Mouse', 2005, 'Studio C')", sm);
//		new test().Explain("insert into movies values('Pride and Prejudice', 2006, 'Studio D')", sm);
//		new test().Explain("insert into movies values('Transformer', 2009, 'Studio E')", sm);
		
		
		/* Error */
//		new test().Explain("insert into movies values('Star Wars', 2001, 'Studio B')", sm);
//		new test().Explain("insert into movies values('movie', 2005, 'Studio G')", sm);
		
		
		
		
//		new test().Explain("create table moviestar(name varchar(20),age integer,moviename varchar(20))", sm);
//		new test().Explain("insert into moviestar values('Smith', 20, 'Star War')", sm);
//		new test().Explain("insert into moviestar values('Jack', 24, 'Titanic')", sm);
//		new test().Explain("insert into moviestar values('Rose', 19, 'Pretty Woman') ", sm);
//		new test().Explain("insert into moviestar values('Tom', 27, 'Star War')", sm);
//		new test().Explain("insert into moviestar values('Vincent', 28, 'Pretty Woman')", sm);
//		new test().Explain("insert into moviestar values('Lucas', 32, 'Transformer')", sm);
//		new test().Explain("insert into moviestar values('Mike', 37, 'Pride and Prejudice')", sm);
//		new test().Explain("insert into moviestar values('Julie', 46, 'Mr and Mrs Smith')", sm);
//		new test().Explain("insert into moviestar values('Peter', 52, 'Long Way')", sm);	
		
		
//		new test().Explain("create view StarInMovie as select name from moviestar, movies where moviestar.moviename = movies.title", sm);	
//		new test().Explain("select * from StarInMovie", sm);
//		
//		
		
		
		
		new test().Explain("create table student(name varchar(20),age integer)", sm);
		new test().Explain("insert into student values('Student1', 20)", sm);
		new test().Explain("insert into student values('Student2', 22)", sm);
		new test().Explain("insert into student values('Student3', 19)", sm);
		new test().Explain("insert into student values('Student4', 17)", sm);
		new test().Explain("insert into student values('Student5', 18)", sm);
		new test().Explain("insert into student values('Student6', 12)", sm);
		new test().Explain("insert into student values('Student7', 17)", sm);
		new test().Explain("insert into student values('Student8', 24)", sm);
		new test().Explain("insert into student values('Student9', 21)", sm);
		
		
//		new test().Explain("create table boy(name varchar(20),age integer)", sm);
//		new test().Explain("insert into boy values('Student12', 20)", sm);
//		new test().Explain("insert into boy values('Student2', 22)", sm);
//		new test().Explain("insert into boy values('Student3', 19)", sm);
//		new test().Explain("insert into boy values('Student4', 17)", sm);
		new test().Explain("select * from student natural join boy", sm);
		
		
		
//		new test().Explain("create index on moviestar(age)", sm);
	
		
//		/* select */
//		new test().Explain("select * from movies", sm);
//		new test().Explain("select * from moviestar", sm);
//		new test().Explain("select * from studio", sm);		
//		new test().Explain("select * from student", sm);
//		new test().Explain("select * from movies, moviestar, studio", sm);
//		new test().Explain("select * from movies where title = 'Star Wars' or year = 2009", sm);
		
//		new test().Explain("select title as movieTitle, name from moviestar, movies where moviestar.moviename = movies.title", sm);
//		new test().Explain("select pro.name as StarName, pro.moviename from movies, (select name, moviename from moviestar where age > 25)pro where pro.moviename = movies.title order by name", sm);
//		new test().Explain("select name, ID from studio where name IN (select studio from movies)", sm);
//		new test().Explain("select name, age from moviestar where movies.age > ALL(select age from student)", sm);
//		new test().Explain("select name from moviestar where movies.age < ANY (select age from student)", sm);
//		new test().Explain("select * from student order by age desc", sm);
		
		
		
		/****!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*****/
//		new test().Explain("delete from student where age > 18", sm);
//		new test().Explain("update movies set studio = 'Studio C' where title = 'Star Wars' or title = 'Pretty Woman'", sm);
//		new test().Explain("select name from moviestar where age > 30", sm);			
		
	
		
		
//		new test().Explain("select from movies", sm);
//		new test().Explain("insert into movies values('movie1', 1999)", sm);
//		new test().Explain("insert into movies values(2000, 234, 'jsdfj')", sm);
//		new test().Explain("create table movies(name char(20), year integer)", sm);
//		new test().Explain("select address from student", sm);
//		new test().Explain("select name, age from moviestar, student", sm);
//		new test().Explain("select address from producer", sm);
		
		
		
		
		
		
		
//	    new test().Explain("create table a (a1 integer)", sm);		
//		new test().Explain("drop table a", sm);	
//		new test().Explain("drop table studio", sm);	
		
		
		
		
		
		
		
		
		
//		new test().Explain("i1.tig", sm);
//		new test().Explain("i2.tig", sm);
//	    new test().Explain("del.tig", sm);
//		new test().Explain("in1.tig", sm);
//		new test().Explain("in2.tig", sm);
//		new test().Explain("in3.tig", sm);
//		new test().Explain("in4.tig", sm);
//		new test().Explain("in5.tig", sm);
//		new test().Explain("in6.tig", sm);
//		new test().Explain("in7.tig", sm);
//		new test().Explain("in8.tig", sm);
//		new test().Explain("create view moviename as select title from Movies", sm);
//		new test().Explain("select * from moviename, MovieStar", sm);
//		new test().Explain("studio.tig", sm);
//		new test().Explain("c1.tig", sm);
//		new test().Explain("studio_i1.tig", sm);
//		new test().Explain("studio_i2.tig", sm);
//		new test().Explain("studio_i3.tig", sm);
//		new test().Explain("q1.tig", sm);
//		new test().Explain("q2.tig", sm);
//		new test().Explain("u1.tig", sm);
//		new test().Explain("q2.tig", sm);
//		new test().Explain("del.tig", sm);
//		new test().Explain("q2.tig", sm);
//		new test().Explain("q3.tig", sm);
//		new test().Explain("ci1.tig", sm);
//		new test().Explain("d1.tig", sm);
//		new test().Explain("create view movieage as select age from Movies natrual join MovieStar", sm);
		
//		int indexNo = sm.GetIndexNo("Movies", "title");
//		IX_IndexHandle ixHandle = null;
//		try{
//			ixHandle = sm.ix.OpenIndex("Movies", indexNo);
//		}
//		catch(java.io.IOException e){
//			
//		}
//		
//		String temp = new String("Star");
//		StringKeyword strK = new StringKeyword(temp, 20);
//		IX_IndexScan ixscan = ixHandle.OpenScan(IX_IndexScan.OP_EQ, strK);
//		
//		RID rid = null;
//		while((rid = ixscan.GetNextEntry())!=null){
//			System.out.println(rid.pageNum + " " + rid.slotNum+"dsfsdf");
//		}
//		System.out.println("finish");
		
		sm.CloseDb();
	} 
	
	public void Explain(String cmdline, SM_Manager sm){
//		String path = "E:\\Science\\CS\\DB\\Project(DB)\\Project\\miniDB\\src\\main\\movie\\"+filename;
		Parse p = null;
		try{
			p=new Parse(cmdline);
		}
		catch(Error e){
			System.out.println(e.getMessage());
			return;
		}
		
		if(p.absyn instanceof CreateIndex){
			try{
				((CreateIndex)p.absyn).CrtIndex(sm);
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
		}
		else
		if(p.absyn instanceof CreateTable){
			try{
				((CreateTable)p.absyn).CrtTable(sm);
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
		}
		else
		if(p.absyn instanceof DropTable){
			try{
				((DropTable)p.absyn).DropRel(sm);
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
		}
		else
		if(p.absyn instanceof DeleteTuple){
			ExecuteEngine engine = new ExecuteEngine(sm);
			Operation query = null;
			try{
				query = engine.PQPlan(((DeleteTuple)p.absyn).CrtAgbPlan(sm));
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
			
			query.Open();
			Operation op = ((Delete_operation)(query)).op;
			RM_FileHandle fh = ((TableScan)(((Select)op).op)).fileHandle;
			
			
//			RID r = new RID(2,9);
//			fh.DeleteRec(r);
			
			while(query.hasNext())
				query.GetNext();

//
//			for(int i=0; i<((Delete_operation)(query)).rid.size(); i++)
//			{
//				RID r = ((Delete_operation)(query)).rid.get(i);
//				fh.DeleteRec(r);
//			}
			query.Close();
//			System.out.println("Delete finished");
		}
		else
		if(p.absyn instanceof Update){
			ExecuteEngine engine = new ExecuteEngine(sm);
			Operation query = null;
			try{
				query = engine.PQPlan(((Update)p.absyn).CrtAgbPlan(sm));
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
			
			query.Open();
			while(query.hasNext())
				query.GetNext();
			query.Close();
			System.out.println("Update finished");
		}
		else
		if(p.absyn instanceof Insert){
			try{
				((Insert)p.absyn).insertTuple(sm);
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
		}
		else
		if(p.absyn instanceof SFW){
			ExecuteEngine engine = new ExecuteEngine(sm);
			Operation query = null;
			try{
				query = engine.PQPlan(((SFW)p.absyn).CrtAgbPlan(sm));
			}
			catch(Error e){
				System.out.println(e.getMessage());
				return;
			}
			
			query.Open();
			
			boolean mark = true;
			while(query.hasNext()){
				Tuple t = query.GetNext();
				
				Tuple n = new Tuple(t.getBytes());

				if(mark){
					for(int i=0; i<t.tuple.size(); i++){
						Element e = t.tuple.get(i);
						System.out.print(e.attrName.toUpperCase());
					}
					mark = false;
					System.out.println();
				}

				for(int i=0; i<t.tuple.size(); i++){
					DataItem value = t.tuple.get(i).value;
					
					if(value instanceof IntegerItem){
						StringBuffer s = new StringBuffer(new String().valueOf(((IntegerItem)value).value));
						s.setLength(Constant.MAXNAME);
						for(int j=0; j<Constant.MAXNAME; j++){
							if(s.charAt(j) != '\0')
								System.out.print(s.charAt(j));
							else
								System.out.print(" ");
						}
					}
					else{
//						((VarcharItem)value).value.setLength(24);
						for(int j=0; j<t.tuple.get(i).length; j++){
							if(((VarcharItem)value).value.charAt(j) != '\0')
								System.out.print(((VarcharItem)value).value.charAt(j));
							else
								System.out.print(" ");
						}
					}
				}
				System.out.println();
			}
			
			query.Close();
		}
		else
		if(p.absyn instanceof CreateView){
			try{
				((CreateView)p.absyn).CrtView(cmdline, sm);
			}
			catch(Error e){
				System.out.println(e.getMessage());
			}
		}
	}
}
